<?php

namespace seecms\db\traits;

use seecms\db\SeeDbQuery;

trait SeeDbExpressWhere
{
    /**
     * 指定XOR查询条件
     *
     * @param mixed $field 查询字段
     * @param mixed $op 查询表达式
     * @param mixed $condition 查询条件
     * @return SeeDbQuery    当前实例自身
     */
    public function whereXor($field, $op = null, $condition = null): SeeDbQuery
    {
        $param = func_get_args();
        array_shift($param);
        $this->parseWhereExp('XOR', $field, $op, $condition, $param);

        return $this;
    }

    /**
     * 指定Like查询条件
     *
     * @param mixed $field 查询字段
     * @param mixed $condition 查询条件
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereLike($field, $condition, string $logic = 'AND'): SeeDbQuery
    {
        $this->parseWhereExp($logic, $field, 'like', $condition, [], true);

        return $this;
    }

    /**
     * 指定NotLike查询条件
     *
     * @param mixed $field 查询字段
     * @param mixed $condition 查询条件
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereNotLike($field, $condition, string $logic = 'AND'): SeeDbQuery
    {
        $this->parseWhereExp($logic, $field, 'not like', $condition, [], true);

        return $this;
    }

    /**
     * 指定Between查询条件
     *
     * @param mixed $field 查询字段
     * @param mixed $condition 查询条件
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereBetween($field, $condition, string $logic = 'AND'): SeeDbQuery
    {
        $this->parseWhereExp($logic, $field, 'between', $condition, [], true);

        return $this;
    }

    /**
     * 指定NotBetween查询条件
     *
     * @param mixed $field 查询字段
     * @param mixed $condition 查询条件
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereNotBetween($field, $condition, string $logic = 'AND'): SeeDbQuery
    {
        $this->parseWhereExp($logic, $field, 'not between', $condition, [], true);

        return $this;
    }

    /**
     * 指定Null查询条件
     *
     * @param mixed $field 查询字段
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereNull($field, string $logic = 'AND'): SeeDbQuery
    {
        $this->parseWhereExp($logic, $field, 'null', null, [], true);

        return $this;
    }

    /**
     * 指定NotNull查询条件
     *
     * @param mixed $field 查询字段
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereNotNull($field, string $logic = 'AND'): SeeDbQuery
    {
        $this->parseWhereExp($logic, $field, 'notnull', null, [], true);

        return $this;
    }

    /**
     * 指定Exists查询条件
     *
     * @param mixed $condition 查询条件
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereExists($condition, string $logic = 'AND'): SeeDbQuery
    {
        $this->options['where'][strtoupper($logic)][] = ['exists', $condition];
        return $this;
    }

    /**
     * 指定NotExists查询条件
     *
     * @param mixed $condition 查询条件
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereNotExists($condition, string $logic = 'AND'): SeeDbQuery
    {
        $this->options['where'][strtoupper($logic)][] = ['not exists', $condition];

        return $this;
    }

    /**
     * 指定In查询条件
     *
     * @param mixed $field 查询字段
     * @param mixed $condition 查询条件
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereIn($field, $condition, string $logic = 'AND'): SeeDbQuery
    {
        $this->parseWhereExp($logic, $field, 'in', $condition, [], true);

        return $this;
    }

    /**
     * 指定NotIn查询条件
     *
     * @param mixed $field 查询字段
     * @param mixed $condition 查询条件
     * @param string $logic 查询逻辑 and or xor
     * @return SeeDbQuery    当前实例自身
     */
    public function whereNotIn($field, $condition, string $logic = 'AND'): SeeDbQuery
    {
        $this->parseWhereExp($logic, $field, 'not in', $condition, [], true);

        return $this;
    }
}